//Copyright 2011 New York City 3D Community

//This file is part of New York City 3D.

//New York City 3D is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.

//New York City 3D is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.

//You should have received a copy of the GNU General Public License
//along with New York City 3D.  If not, see <http://www.gnu.org/licenses/>.

package nyc3d.street;

import com.jme3.asset.AssetManager;
import com.jme3.light.PointLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;

/**
 *
 */
public class PedestrianWalkSignalSide {
    PedestrianWalkSignal parentWalkSignal;
    Geometry goRect, stopRect, currentRect;
    PointLight goLight, stopLight, currentLight;
    public enum Type{MAIN, SECONDARY};
    public enum Orientation{TOWARD, AWAY};
    private boolean inCountdown;
    private Type type;
    private Orientation orientation;
    private long time, blinkTime, waitTime;

    public PedestrianWalkSignalSide(Type type, Orientation orientation, AssetManager assetManager, Vector3f translation, Vector3f rotation, PedestrianWalkSignal parentWalkSignal, boolean orientationSwitched){
        this.type = type;
        this.orientation = orientation;
        this.parentWalkSignal = parentWalkSignal;
        inCountdown = false;
        time = System.currentTimeMillis();
        blinkTime = 500;
        waitTime = 500;

        goRect = new Geometry(parentWalkSignal.getName() + " Go", new Box(Vector3f.ZERO, .001f, .8f, .36f));
        Material matGoRect = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        matGoRect.setColor("Color", ColorRGBA.White);
        goRect.setMaterial(matGoRect);

        if (orientationSwitched){
            goRect.setLocalTranslation(translation.add(new Vector3f(-1.25f, 0, .385f)));
        }
        else{
            if (orientation.equals(Orientation.AWAY)){
                if (type.equals(Type.MAIN))
                    goRect.setLocalTranslation(translation.add(new Vector3f(-.375f, 0, .385f)));
                else
                    goRect.setLocalTranslation(translation.add(new Vector3f(.375f, 0, .385f)));
            }
            else{
                if (type.equals(Type.MAIN))
                    goRect.setLocalTranslation(translation.add(new Vector3f(.375f, 0, -.385f)));
                else
                    goRect.setLocalTranslation(translation.add(new Vector3f(-.375f, 0, -.385f)));
            }
        }
        
        stopRect = new Geometry(parentWalkSignal.getName() + " Go", new Box(Vector3f.ZERO, .001f, .8f, .36f));
        Material matStopRect = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        matStopRect.setColor("Color", ColorRGBA.Red);
        stopRect.setMaterial(matStopRect);

        if (orientation.equals(Orientation.AWAY)){
            if (type.equals(Type.SECONDARY)){
                if (orientationSwitched)
                    stopRect.setLocalTranslation(translation.add(new Vector3f(-.375f, 0, .385f)));
                else
                    stopRect.setLocalTranslation(translation.add(new Vector3f(-.375f, 0, .385f)));
            }
            else
                stopRect.setLocalTranslation(translation.add(new Vector3f(-.375f, 0, -.385f)));
        } else{
            if (type.equals(Type.SECONDARY))
                stopRect.setLocalTranslation(translation.add(new Vector3f(.375f, 0, -.385f)));
            else
                stopRect.setLocalTranslation(translation.add(new Vector3f(.375f, 0, .385f)));
        }

        if (type.equals(Type.SECONDARY)){
            goRect.rotate(0, (FastMath.PI / -2f), 0);
            stopRect.rotate(0, (FastMath.PI / -2f), 0);
        }

        goLight = new PointLight();
        goLight.setPosition(goRect.getWorldTranslation().add(parentWalkSignal.getNode().getLocalTranslation()));
        goLight.setColor(ColorRGBA.White.clone().multLocal(.05f));
        goLight.setRadius(20);

        stopLight = new PointLight();
        stopLight.setPosition(stopRect.getWorldTranslation().add(parentWalkSignal.getNode().getLocalTranslation()));
        stopLight.setColor(ColorRGBA.Red.clone().multLocal(.05f));
        stopLight.setRadius(20);

        if (type.equals(Type.MAIN)){
            currentRect = goRect;
            currentLight = goLight;
            
        }
        else{
            currentRect = stopRect;
            currentLight = stopLight;
        }

        parentWalkSignal.getParentNode().addLight(currentLight);
        parentWalkSignal.getNode().attachChild(currentRect);
    }

    public PointLight getCurrentLight() {
        return currentLight;
    }

    public void setCurrentLight(PointLight currentLight) {
        this.currentLight = currentLight;
    }

    public Geometry getCurrentRect() {
        return currentRect;
    }

    public void setCurrentRect(Geometry currentRect) {
        this.currentRect = currentRect;
    }

    public PointLight getGoLight() {
        return goLight;
    }

    public void setGoLight(PointLight goLight) {
        this.goLight = goLight;
    }

    public Geometry getGoRect() {
        return goRect;
    }

    public void setGoRect(Geometry goRect) {
        this.goRect = goRect;
    }

    public Orientation getOrientation() {
        return orientation;
    }

    public void setOrientation(Orientation orientation) {
        this.orientation = orientation;
    }

    public PedestrianWalkSignal getParentWalkSignal() {
        return parentWalkSignal;
    }

    public void setParentWalkSignal(PedestrianWalkSignal parentWalkSignal) {
        this.parentWalkSignal = parentWalkSignal;
    }

    public PointLight getStopLight() {
        return stopLight;
    }

    public void setStopLight(PointLight stopLight) {
        this.stopLight = stopLight;
    }

    public Geometry getStopRect() {
        return stopRect;
    }

    public void setStopRect(Geometry stopRect) {
        this.stopRect = stopRect;
    }

    public Type getType() {
        return type;
    }

    public void setType(Type type) {
        this.type = type;
    }

    public boolean isInCountdown() {
        return inCountdown;
    }

    public void setInCountdown(boolean inCountdown) {
        this.inCountdown = inCountdown;
    }

    public long getBlinkTime() {
        return blinkTime;
    }

    public void setBlinkTime(long blinkTime) {
        this.blinkTime = blinkTime;
    }

    public long getTime() {
        return time;
    }

    public void setTime(long time) {
        this.time = time;
    }

    public long getWaitTime() {
        return waitTime;
    }

    public void setWaitTime(long waitTime) {
        this.waitTime = waitTime;
    }
}